import type { DataAttrsItem } from '../../../../../lib/abstract/base_destructible'
import type { GreasyForkElements } from '../../../../../types/constants/personalization/greasy_fork'
import type { ComponentStyleIdType } from '../../../../../types/interfaces'
import type { IScriptData } from '../../../../../user_center/tab/personalization/custom_css/theme/others/greasy_fork/module/script_processor/types'
import { BaseModule } from '../../../../../lib/abstract'
import {
  ComponentStyleId,
  logger,
  PAGE_ELEMENTS,
  SUPPORTED_PLATFORMS,
} from '../../../../../types/constants'
import { ConfigProcessor } from '../../../../../user_center/tab/personalization/custom_css/theme/others/greasy_fork/module/config_processor'
import { ScriptProcessor } from '../../../../../user_center/tab/personalization/custom_css/theme/others/greasy_fork/module/script_processor'
import { ConfigManager } from '../../../../config_manager'

interface Config {
  enabled?: boolean
}

export class GreasyForkScriptInstalls extends BaseModule {
  readonly id: string = 'greasy_fork_script_installs'
  readonly styleId: string = ComponentStyleId[this.name]
  isInitialized: boolean = false
  readonly supportedPlatforms: string[] = ConfigManager.getInstance().moduleSupportedPlatforms(this.name)
  private static instance: GreasyForkScriptInstalls
  private scriptProcessor: ScriptProcessor = ScriptProcessor.getInstance()
  elements: GreasyForkElements = PAGE_ELEMENTS[SUPPORTED_PLATFORMS.GREASY_FORK]
  private readonly dataAttrs: Record<
    'processed',
    DataAttrsItem
  > = {
    processed: { type: 'data', name: 'processed-installs' },
  }

  config: Config = {
    enabled: true,
  }

  get name(): ComponentStyleIdType {
    return 'GreasyForkScriptInstalls'
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): GreasyForkScriptInstalls {
    if (!GreasyForkScriptInstalls.instance) {
      GreasyForkScriptInstalls.instance = new GreasyForkScriptInstalls()
    }
    return GreasyForkScriptInstalls.instance
  }

  core(): void {
    this.loadConfig()

    if (!this.config.enabled)
      return

    this.processAllScriptElements()
  }

  onToggleCallback(_id: string, checked: boolean): void {
    super.onToggleCallback(_id, checked)
  }

  /**
   * 处理所有脚本元素
   */
  processAllScriptElements(): void {
    // 处理每个脚本元素
    $(this.scriptProcessor.SCRIPT_LIST_SELECTOR).each((_, element) => {
      this.processScriptElement($(element))
    })
  }

  /**
   * 处理单个脚本元素
   */
  processScriptElement($element: JQuery<HTMLElement>): void {
    // 检查是否已经处理过（避免重复处理）
    if ($element.data(this.dataAttrs.processed.name))
      return

    $element.data(this.dataAttrs.processed.name, true)
    this.tracker.dataAttrs($element, this.dataAttrs.processed.type, this.dataAttrs.processed.name)

    const data: IScriptData = this.scriptProcessor.getScriptData($element)

    // 添加安装量级别处理
    this.processInstallLevels($element, data)
    // 更新用户头像
    this.scriptProcessor.updateAvatar($element)
  }

  /**
   * 处理安装量级别显示
   */
  private processInstallLevels($element: JQuery<HTMLElement>, data: IScriptData): void {
    // 处理日安装量
    const dailyLevel = ConfigProcessor.getInstallLevel('daily', data.dailyInstalls)
    if (dailyLevel) {
      const $dailyInstalls = $element.find('dd.script-list-daily-installs')
      const addClass = `daily-installs ${dailyLevel.class}`
      $dailyInstalls.addClass(addClass)
      this.tracker.addedClasses($dailyInstalls, addClass)
    }

    // 处理总安装量
    const totalLevel = ConfigProcessor.getInstallLevel('total', data.totalInstalls)
    if (totalLevel) {
      const $totalInstalls = $element.find('dd.script-list-total-installs')
      const addClass = `total-installs ${totalLevel.class}`
      $totalInstalls.addClass(addClass)
      this.tracker.addedClasses($totalInstalls, addClass)
    }
  }

  applyConfig(config: Partial<Config>): void {
    super.updateConfig(config)

    this.processAllScriptElements()

    logger.info(`[${this.name}] Config updated and apply`, this.config)
  }

  getStyles(): string {
    return ``
  }
}
